package com.efounder.agency.utils;

import android.content.Context;
import android.util.Log;

import com.efounder.builder.base.data.EFDataSet;
import com.efounder.builder.base.data.EFRowSet;
import com.efounder.util.ToastUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TaskDataParser {
    public static final String KEY_ELEMENTNAME = "elementname";
    public static final String KEY_ELEMENTTEXT = "elementtext";

    public static final String OPERATION_KEY_CHILD = "child";
    public static final String OPERATION_KEY_PARENT = "parent";
    private Context mContext;

    public TaskDataParser(Context context) {
        this.mContext = context;

    }

    public EFDataSet parseFormData(EFDataSet rootDataSet) {
        List<EFRowSet> formRowSets = new ArrayList<EFRowSet>();
        recurTraversal(rootDataSet, "form", formRowSets);
        if (formRowSets == null || formRowSets.size() < 1) {

            return null;
        }
        EFRowSet formEfRowSet = formRowSets.get(0);
        EFDataSet tableDataSet = formEfRowSet.getChildDataSet();

        return tableDataSet;
    }

    /**
     * 解析数据
     *
     * @param rootDataSet
     * @param xmlKey
     * @return
     */
    public EFDataSet parseFormData(EFDataSet rootDataSet, String xmlKey) {
        List<EFRowSet> formRowSets = new ArrayList<EFRowSet>();
        recurTraversal(rootDataSet, xmlKey, formRowSets);

        if (formRowSets == null || formRowSets.size() < 1) {

            return null;
        }
        EFRowSet formEfRowSet = formRowSets.get(0);
        EFDataSet tableDataSet = formEfRowSet.getChildDataSet();

        return tableDataSet;
    }

    /**
     * 递归遍历
     *
     * @param efDataSet
     */
    private void recurTraversal(EFDataSet dataSet, String elementName,
                                List<EFRowSet> elementRowSets) {

        if (dataSet == null) {
            ToastUtil.showToast(mContext, "数据加载失败，请联系管理员");
            return;
        }
        List<EFRowSet> list = dataSet.getRowSetArray();
        if (list == null) {
            ToastUtil.showToast(mContext, "数据加载失败，请联系管理员");
            return;
        }
        for (EFRowSet rowSet : list) {
            String xmlElementName = rowSet.getString("elementname", "");
            // Log.i("OA", "-----" + rowSet.getDataMap());
            if (elementName.equals(xmlElementName)) {
                elementRowSets.add(rowSet);
            } else {
                EFDataSet childDataSet = rowSet.getChildDataSet();
                if (childDataSet != null) {
                    recurTraversal(childDataSet, elementName, elementRowSets);
                }
            }
        }
    }

    /**
     * 递归打印
     *
     * @param dataSet
     */
    public static void recurPrint(EFDataSet dataSet) {
        @SuppressWarnings("unchecked")
        List<EFRowSet> rowSets = dataSet.getRowSetArray();
        for (EFRowSet rowSet : rowSets) {
            Log.i("", "recurPrint-----" + rowSet.getDataMap().toString());
            EFDataSet chilDataSet = rowSet.getChildDataSet();
            if (chilDataSet != null) {
                recurPrint(chilDataSet);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public List<Map<String, Object>> parseOperation(EFDataSet rootDataSet) {
        // 获取operation 下所有的 table 的 EFRowSet Array
        List<EFRowSet> operationRowSets = new ArrayList<EFRowSet>();
        recurTraversal(rootDataSet, "operation", operationRowSets);

        EFRowSet operationEfRowSet = operationRowSets.get(0);
        EFDataSet tableDataSet = operationEfRowSet.getChildDataSet();
        // table数据源
        List<EFRowSet> tableRowSets = tableDataSet.getRowSetArray();
        // 一级
        List<Map<String, Object>> oneLevelList = new ArrayList<Map<String, Object>>();
        for (EFRowSet tableRowSet : tableRowSets) {

            // tr数据源
            List<EFRowSet> trRowSets = tableRowSet.getChildDataSet()
                    .getRowSetArray();

            String tdContentValue = null;
            // 二级
            Map<String, Object> oneLevelMap = null;
            List<Map<String, Object>> twoLevelList = new ArrayList<Map<String, Object>>();
            for (EFRowSet trRowSet : trRowSets) {
                String trParentAttr = trRowSet.getString("parent", "");
                EFRowSet tdRowSet = (EFRowSet) trRowSet.getChildDataSet()
                        .getRowSetArray().get(0);
                EFRowSet tdContentEfRowSet = (EFRowSet) tdRowSet
                        .getChildDataSet().getRowSetArray().get(0);// 例如 input

                if ("".equals(trParentAttr)) {// 如果parent是 ""，放入一级List
                    boolean isHidden = tdContentEfRowSet.getString("type", "")
                            .equals("hidden");
                    boolean hasValue = !tdContentEfRowSet
                            .getString("value", "").equals("");
                    if (!isHidden && hasValue) {
                        tdContentValue = tdContentEfRowSet.getString("value",
                                "XXX");
                        oneLevelMap = tdContentEfRowSet.getAttriMap();// 生成一级map
                        oneLevelList.add(oneLevelMap);
                        oneLevelMap.put(OPERATION_KEY_PARENT, null);
                        oneLevelMap.put(OPERATION_KEY_CHILD, twoLevelList);// 一级map放入二级list
                    } else {// XXX 所有隐藏项，放入二级菜单
                        Map<String, Object> twoLevelMap = tdContentEfRowSet
                                .getAttriMap();// 生成二级map
                        twoLevelList.add(twoLevelMap);
                        twoLevelMap.put(OPERATION_KEY_PARENT, oneLevelMap);
                        twoLevelMap.put(OPERATION_KEY_CHILD,
                                new ArrayList<Map<String, Object>>());
                    }

                } else if (trParentAttr.equals(tdContentValue)) {// 放入二级菜单
                    boolean isHidden = tdContentEfRowSet.getString("type", "")
                            .equals("hidden");
                    if (!isHidden) {
                        Map<String, Object> twoLevelMap = tdContentEfRowSet
                                .getAttriMap();// 生成二级map
                        twoLevelList.add(twoLevelMap);
                        // 三级
                        List<Map<String, Object>> threeLevelList = new ArrayList<Map<String, Object>>();
                        twoLevelMap.put(OPERATION_KEY_PARENT, oneLevelMap);
                        twoLevelMap.put(OPERATION_KEY_CHILD, threeLevelList);

                        if (tdContentEfRowSet.getChildDataSet() != null) {
                            // option--数据源（例如 <user> 下的元素）
                            List<EFRowSet> optionRowSets = tdContentEfRowSet
                                    .getChildDataSet().getRowSetArray();
                            for (EFRowSet optionRowSet : optionRowSets) {
                                Map<String, Object> threeLevelMap = optionRowSet
                                        .getAttriMap();
                                threeLevelList.add(threeLevelMap);
                                EFDataSet optionContentDataSet = optionRowSet
                                        .getChildDataSet();
                                if (optionContentDataSet != null) {
                                    EFRowSet optionContentRowSet = (EFRowSet) optionContentDataSet
                                            .getRowSetArray().get(0);
                                    String optionText = optionContentRowSet
                                            .getString(KEY_ELEMENTTEXT, "");
                                    threeLevelMap.put(KEY_ELEMENTTEXT,
                                            optionText);
                                    threeLevelMap.put(OPERATION_KEY_PARENT,
                                            twoLevelMap);
                                }
                            }
                        }
                    }
                }
            }
        }

        printOperation(oneLevelList);
        return oneLevelList;
    }

    @SuppressWarnings("unchecked")
    public static void printOperation(List<Map<String, Object>> oneLevelList) {
        for (Map<String, Object> oneLevelMap : oneLevelList) {
            Log.i("yqs", "一级-----" + hierarchyMap2String(oneLevelMap));
            List<Map<String, Object>> twoLevelList = (List<Map<String, Object>>) oneLevelMap
                    .get("child");
            for (Map<String, Object> twoLevelMap : twoLevelList) {
                Log.i("yqs", "二级----- -----" + hierarchyMap2String(twoLevelMap));
                List<Map<String, Object>> threeLevelList = (List<Map<String, Object>>) twoLevelMap
                        .get("child");
                for (Map<String, Object> threeLevelMap : threeLevelList) {
                    Log.i("yqs", "三级----- ----- -----"
                            + hierarchyMap2String(threeLevelMap));
                }
            }
        }
    }

    /**
     * 层级map转成String 当map 同时持有parent和child时，直接打印会报StackOverFlow 异常
     *
     * @param map
     * @return
     */
    @SuppressWarnings("unchecked")
    public static String hierarchyMap2String(Map<String, Object> map) {
        Set<String> keys = map.keySet();
        StringBuffer buffer = new StringBuffer("{ ");
        for (String key : keys) {
            if (OPERATION_KEY_PARENT.equals(key)) {// 父 elementname
                Map<String, Object> parentMap = (Map<String, Object>) map
                        .get(key);
                buffer.append(key)
                        .append("=父类元素名称-")
                        .append(parentMap == null ? "null" : parentMap
                                .get("elementname")).append(", ");
            } else if (OPERATION_KEY_CHILD.equals(key)) {// 子
                List<Map<String, Object>> childMaps = (List<Map<String, Object>>) map
                        .get(key);
                buffer.append(key).append("=子元素个数-")
                        .append(childMaps == null ? "null" : childMaps.size())
                        .append(", ");

            } else {
                buffer.append(key).append("=").append(map.get(key))
                        .append(", ");
            }
        }
        String mapString = buffer.substring(0, buffer.length() - 1) + " }";
        return mapString;
    }

}
